package com.whfc.common.util;

import com.google.common.base.Preconditions;
import org.apache.commons.lang3.StringUtils;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2019/7/17 10:04
 */
public class ByteUtil {

    /**
     * 3字节 转换 十进制
     *
     * @param bytes
     * @return
     */
    public static int low3ByteToInt(byte[] bytes) {
        Preconditions.checkArgument(bytes.length >= 3, "数组长度不能小于3");
        return ((bytes[0] & 0x000000ff) << 16)
                | ((bytes[1] & 0x000000ff) << 8)
                | (bytes[2] & 0x000000ff);
    }

    /**
     * 3字节 转换 十进制
     *
     * @param bytes
     * @return
     */
    public static int low3ByteToInt(int[] bytes) {
        Preconditions.checkArgument(bytes.length >= 3, "数组长度不能小于3");
        return ((bytes[0] & 0x000000ff) << 16) | ((bytes[1] & 0x000000ff) << 8) | (0x000000ff & bytes[2]);
    }

    /**
     * 2字节转换十进制
     *
     * @param bytes
     * @return
     */
    public static int low2ByteToIntBE(int... bytes) {
        Preconditions.checkArgument(bytes.length >= 2, "数组长度不能小于2");
        return ((bytes[1] & 0x000000ff) << 8) | (0x000000ff & bytes[0]);
    }

    /**
     * 2字节转换十进制
     *
     * @param bytes
     * @return
     */
    public static int getSignedShort(int... bytes) {
        Preconditions.checkArgument(bytes.length >= 2, "数组长度不能小于2");
        return (short) ((bytes[1]) << 8) | (bytes[0]);
    }

    /**
     * 3字节转换十进制
     *
     * @param bytes
     * @return
     */
    public static int low3ByteToIntBE(int... bytes) {
        Preconditions.checkArgument(bytes.length >= 3, "数组长度不能小于4");
        return ((bytes[2] & 0x000000ff) << 16) | ((bytes[1] & 0x000000ff) << 8) | (bytes[0] & 0x000000ff);
    }

    /**
     * 4字节转换十进制
     *
     * @param bytes
     * @return
     */
    public static long low4ByteToLongBE(int... bytes) {
        Preconditions.checkArgument(bytes.length >= 4, "数组长度不能小于4");
        return ((bytes[3] & 0x00000000ffL) << 24)
                | ((bytes[2] & 0x00000000ffL) << 16)
                | ((bytes[1] & 0x00000000ffL) << 8)
                | ((bytes[0] & 0x00000000ffL));
    }

    /**
     * 6字节 转换十进制
     *
     * @param bytes
     * @return
     */
    public static long low6ByteToLong(byte[] bytes) {
        Preconditions.checkArgument(bytes.length >= 6, "数组长度不能小于6");
        return ((bytes[0] & 0x00000000ffL) << 40)
                | ((bytes[1] & 0x00000000ffL) << 32)
                | ((bytes[2] & 0x00000000ffL) << 24)
                | ((bytes[3] & 0x00000000ffL) << 16)
                | ((bytes[4] & 0x00000000ffL) << 8)
                | ((bytes[5] & 0x00000000ffL));
    }

    /**
     * 6字节 转换 十进制
     *
     * @param bytes
     * @return
     */
    public static long low6ByteToLong(int[] bytes) {
        Preconditions.checkArgument(bytes.length >= 6, "数组长度不能小于6");
        return
                ((bytes[0] & 0x00000000ffL) << 40)
                        | ((bytes[1] & 0x00000000ffL) << 32)
                        | ((bytes[2] & 0x00000000ffL) << 24)
                        | ((bytes[3] & 0x00000000ffL) << 16)
                        | ((bytes[4] & 0x00000000ffL) << 8)
                        | ((bytes[5] & 0x00000000ffL));
    }

    public static byte[] extractLow3Byte(long value) {
        byte[] bytes = new byte[3];
        bytes[0] = (byte) ((value >> 16) & 0xFF);
        bytes[1] = (byte) ((value >> 8) & 0xFF);
        bytes[2] = (byte) (value & 0xFF);
        return bytes;
    }

    /**
     * 提取bit
     *
     * @param value
     * @param bitIndex
     * @return
     */
    public static int getBit(int value, int bitIndex) {
        return (value >> bitIndex) & 0x00000001;
    }

    /**
     * 截取多个bit
     *
     * @param data
     * @param startIndex
     * @param endIndex
     * @return
     */
    public static int getBit(int data, int startIndex, int endIndex) {
        Preconditions.checkState(startIndex <= endIndex);
        String bitStr = getBitStr(data, startIndex, endIndex);
        return Integer.parseInt(bitStr, 2);
    }

    /**
     * 提取多个bit字符串
     *
     * @param data
     * @param startIndex
     * @param endIndex
     * @return
     */
    public static String getBitStr(int data, int startIndex, int endIndex) {
        StringBuffer str = new StringBuffer();
        for (int i = startIndex; i <= endIndex; i++) {
            str.append(ByteUtil.getBit(data, i));
        }
        return str.reverse().toString();
    }

    /**
     * 数字转换成十六进制字符串
     *
     * @param data
     * @return
     */
    public static String toHexString(int data) {
        String hexStr = Integer.toHexString(data);
        StringBuffer buffer = new StringBuffer();
        if (hexStr.length() < 2) {
            for (int i = 0; i < 2 - hexStr.length(); i++) {
                buffer.append(0);
            }
        }
        buffer.append(hexStr);
        return buffer.toString();
    }

    /**
     * 从十六进制字符串解析数字
     *
     * @param hexStr
     * @return
     */
    public static int fromHexString(String hexStr) {
        if (StringUtils.isEmpty(hexStr)) {
            return 0;
        }
        int data = Integer.parseInt(hexStr, 16);
        return data;
    }

    /**
     * 字节数组转换成十六进制字符串
     *
     * @param dataArr
     * @return
     */
    public static String toHexString(int[] dataArr) {
        StringBuffer stringBuffer = new StringBuffer();
        for (int data : dataArr) {
            stringBuffer.append(toHexString(data));
        }
        return stringBuffer.toString();
    }

    /**
     * 转换数据(string->int[])
     *
     * @param strData
     * @return 整形数组
     */
    public static int[] transform(String strData) {
        boolean isOdd = strData.length() % 2 != 0;
        int len = strData.length() / 2 + (isOdd ? 1 : 0);
        int[] arr = new int[len];
        int startIndex = 0;
        int endIndex = 0;
        for (int i = 0; i < arr.length; i++) {
            startIndex = endIndex;
            endIndex = (i == 0 && isOdd) ? startIndex + 1 : startIndex + 2;
            String str = strData.substring(startIndex, endIndex);
            arr[i] = Integer.parseInt(str, 16);
        }
        return arr;
    }

    /**
     * 转换数据(int[]->string)
     *
     * @param bytes
     * @return
     */
    public static String transform(int[] bytes) {
        StringBuffer stringBuffer = new StringBuffer();
        for (int data : bytes) {
            stringBuffer.append(toHexString(data));
        }
        return stringBuffer.toString();
    }

    public static void main(String[] args) {
        String str = "FFFFFE0000000001";
        String str1 = transform(transform(str));
        System.out.println(str);
        System.out.println(str1);

        str = "2B7E151628AED2A6ABF7158809CF4F3C";
        str1 = transform(transform(str));
        System.out.println(str);
        System.out.println(str1);
    }
}
